import subprocess
import re
import sys
from typing import List, Dict, Tuple
from pathlib import Path
from collections import OrderedDict

def get_project_root():
    if "__file__" in globals():
        root = Path(__file__).resolve().parent
    else:
        root = Path(sys.argv[0]).resolve().parent
    return root


PROJECT_ROOT = get_project_root()
# log
RMSL_LOG_PATH = PROJECT_ROOT / "viewer.log"
# ffmpeg
FFMPEG = str(PROJECT_ROOT / "ffmpeg/ffmpeg.exe")


class UVCFormatEnumerator:
    def __init__(self, device_name: str):
        """
        :param device_name: Windows设备名，如 "video=USB Camera"
        """
        self.device_name = device_name

    def get_supported_formats(self) -> List[Dict]:
        """获取所有支持的格式"""
        cmd = [
            FFMPEG,
            '-list_options', 'true',
            '-f', 'dshow',
            '-i', f'video={self.device_name}'
        ]

        try:
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                encoding='utf-8',
                errors='ignore'
            )

            # ffmpeg的设备信息在stderr中
            output = result.stderr
            return self._parse_formats(output)

        except Exception as e:
            print(f"Error: {e}")
            return []

    def _parse_formats(self, output: str) -> List[Dict]:
        """解析ffmpeg输出"""
        formats = []
        current_pixel_format = None

        # 正则匹配示例：
        # [dshow @ 000001] pixel_format=yuyv422  min s=640x480 fps=30 max s=1920x1080 fps=30
        # [dshow @ 000001]   vcodec=mjpeg  min s=1920x1080 fps=30 max s=1920x1080 fps=30

        for line in output.split('\n'):
            # 匹配像素格式
            pixel_match = re.search(r'pixel_format=(\w+)', line)
            if pixel_match:
                current_pixel_format = pixel_match.group(1)

            # 匹配编码格式
            codec_match = re.search(r'vcodec=(\w+)', line)
            if codec_match:
                current_pixel_format = codec_match.group(1)

            # 匹配分辨率和帧率
            # 格式1: min s=640x480 fps=30 max s=1920x1080 fps=30
            range_match = re.search(
                r'min s=(\d+)x(\d+) fps=([\d.]+) max s=(\d+)x(\d+) fps=([\d.]+)',
                line
            )
            if range_match and current_pixel_format:
                min_w, min_h, min_fps, max_w, max_h, max_fps = range_match.groups()
                formats.append({
                    'format': current_pixel_format.upper(),
                    'width': int(max_w),
                    'height': int(max_h),
                    'fps': float(max_fps),
                    'min_width': int(min_w),
                    'min_height': int(min_h),
                    'min_fps': float(min_fps)
                })

            # 格式2: s=1920x1080 fps=30
            simple_match = re.search(r's=(\d+)x(\d+)\s+fps=([\d.]+)', line)
            if simple_match and current_pixel_format:
                w, h, fps = simple_match.groups()
                formats.append({
                    'format': current_pixel_format.upper(),
                    'width': int(w),
                    'height': int(h),
                    'fps': float(fps)
                })

        return formats

    @staticmethod
    def remove_duplicates(resolutions):
        # 创建一个字典，key为唯一标识，value为配置
        unique_dict = {}
        for res in resolutions:
            key = (res['format'], res['width'], res['height'], res['fps'])
            if key not in unique_dict:
                unique_dict[key] = res
        return list(unique_dict.values())


# 使用示例
if __name__ == '__main__':
    camera_ids = ["RMSL321_RGB", "RMSL321_DEPTH", "RMSL321_IR"]
    for cam_id in camera_ids:
        enum = UVCFormatEnumerator(cam_id)  # 替换为你的设备名
        formats = enum.get_supported_formats()
        formats = enum.remove_duplicates(formats)

        print(f"{cam_id} 找到 {len(formats)} 个格式配置：\n")

        for fmt in formats:
            print(f"{fmt['format']:10} {fmt['width']}x{fmt['height']} @ {fmt['fps']}fps")